home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
byte1286.arc
/
AITKEN.F77
< prev
next >
Wrap
Text File
|
1986-12-05
|
10KB
|
304 lines
PROGRAM GAUSS
C
C FORTRAN-77 PROGRAM TO APPROXIMATE DEFINITE INTEGRALS. VERSION: 4-14-86
C
C DAVID M. SMITH
C MATHEMATICS DEPARTMENT
C LOYOLA MARYMOUNT UNIVERSITY
C LOS ANGELES, CA 90045
C
C
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
DIMENSION TABLE(20)
C
C UNIT NUMBERS: KW - SCREEN OUTPUT
C KR - KEYBOARD INPUT
C KF - OUTPUT TO FILE 'GAUSSQ.OUT'
C
KW = 6
KR = 5
KF = 8
OPEN(KF,FILE='GAUSSQ.OUT',STATUS='NEW')
C
C FORTRAN-77 COMPILERS ALLOW THESE 5 INPUT VALUES TO BE
C ENTERED IN FREE FORMAT. I.E., TO ENTER NFCT = 2 TYPE THE
C 2 IN COLUMN 1 AND THEN TYPE CARRIAGE RETURN. TO ENTER
C A = 1 TYPE 1. OR 1.0 THEN RETURN. THE DECIMAL POINT
C SHOULD BE TYPED FOR THE REAL VALUES (A AND B).
C
C MOST FORTRAN-66 COMPILERS WHICH SUPPORT IF-THEN-ELSE
C REQUIRE THAT THE INTEGERS BE TYPED RIGHT-JUSTIFIED,
C SO THAT TO ENTER NFCT = 2 TYPE 4 BLANKS AND THEN THE 2
C IN COLUMN 5.
C
110 WRITE (KW,120)
120 FORMAT(/' Enter (1 item per line): NFCT / KL / IOFLAG / A / B.'
* /7X,'(Format for NFCT,KL,IOFLAG is I5, for A,B is F25.0.'/
* /' Integrate function NFCT from A to B (NFCT=0 to quit)',
* /' There will be KL lines in the Gauss',
* ' column of the table.'/
* ' IOFLAG = 1 causes the output to be saved in file',
* ' GAUSSQ.OUT.'/)
C
READ (KR,130) NFCT
130 FORMAT(I5)
IF (NFCT.EQ.0) STOP
READ (KR,140) KL,IOFLAG,A,B
140 FORMAT(I5/I5/F25.0/F25.0)
C
IF (NFCT.LE.0) STOP
C
KPRT = 1
IF (IOFLAG.EQ.1) KPRT = 2
CALL GAUSSQ(A,B,NFCT,KL,TABLE,KPRT,KF,KW)
DO 170 J = 1, 20
WRITE (KW,150)
150 FORMAT(/' ENTER 1 FOR THE NEXT AITKEN COLUMN, 0 TO QUIT.',
* ' (I1)')
READ (KR,160) KOPT
160 FORMAT(I1)
IF (KOPT.NE.1) GO TO 110
CALL AITKEN(TABLE,KL,KPRT,KF,KW)
KL = KL - 2
IF (KL.LT.3) GO TO 110
170 CONTINUE
GO TO 110
C
END
SUBROUTINE GAUSSQ(A,B,NFCT,KL,TABLE,KPRT,KF,KW)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
C DAVID M. SMITH 4-14-86
C
C ITERATIVE GAUSS QUADRATURE. FUNCTION NUMBER NFCT IS INTEGRATED FROM
C A TO B PRODUCING KL LINES IN TABLE USING
C 1, 2, 4, 8, 16, ..., 2**(KL-1) SUBINTERVALS.
C
C IF KPRT IS 1 THE TABLE IS WRITTEN ON UNIT KW.
C IF KPRT IS 2 THE TABLE IS ALSO WRITTEN ON UNIT KF.
C
C IN THE TABLE WHICH IS WRITTEN:
C
C N IS THE NUMBER OF SUBINTERVALS USED,
C GAUSS IS THE GAUSS QUADRATURE APPROXIMATION TO THE INTEGRAL,
C TOTAL NF IS THE TOTAL NUMBER OF FUNCTION EVALUATIONS DONE SO FAR,
C EST S.D. IS A CONSERVATIVE ESTIMATE OF THE NUMBER OF SIGNIFICANT
C DIGITS WHICH ARE CORRECT IN THAT LINE
C
C THE EXTERNAL FUNCTION CALLED IS F(X,NFCT) FOR THE FUNCTION BEING
C INTEGRATED.
C
DIMENSION TABLE(20)
C
C SET EPS TO THE SIZE OF THE ROUNDING ERRORS FOR A GIVEN
C MACHINE. EPS = 1.0E-7 FOR 32 BIT MACHINES (SINGLE
C PRECISION) OR 1.0E-16 (DOUBLE PRECISION).
C
EPS = 1.0E-16
C
C CHECK FOR ERRORS.
C
IF (KL.LT.1) THEN
WRITE (KW,110) KL
110 FORMAT(/' ERROR IN GAUSSQ. KL=',I5,'. IT SHOULD BE AT ',
* 'LEAST 1.')
DO 120 J = 1, 20
120 TABLE(J) = -3.1E+31
RETURN
ENDIF
C
C DO GAUSS QUADRATURE FOR THE INTEGRAL OF F(X) FROM A TO B.
C
NLINES = KL
SQRT3 = DSQRT(3.0D0)
NSUBS = 1
NFUNCT = 0
C
IF (KPRT.GE.1) THEN
WRITE (KW,130) NFCT,NLINES
IF (KPRT.GE.2) WRITE (KF,130) NFCT,NLINES
130 FORMAT(/' GAUSS INTEGRATION OF FUNCTION ',I3,'. THERE',
* ' ARE',I3,' LINES IN THE TABLE.')
WRITE (KW,140) A,B
IF (KPRT.GE.2) WRITE (KF,140) A,B
140 FORMAT(/' THE LIMITS OF INTEGRATION ARE:'/3X,D23.16,
* ' TO ',D23.16/)
ENDIF
C
DO 180 JLINE = 1, NLINES
C
C THE KTH SUBINTERVAL IS (AK,BK). THE GAUSS APPROXIMATION
C FOR THE INTEGRAL IS: XH*(F(XM-XR) + F(XM+XR)), WHERE
C XH = (BK-AK)/2, XM = (AK+BK)/2, XR = XH/(2*SQRT(3)),
C AK = A + (K-1)*(B-A)/NSUBS, BK = A + K*(B-A)/NSUBS.
C
XH = (B-A)/NSUBS
XH2 = XH/2.0
XR = XH2/SQRT3
START1 = A - XH2 - XR
START2 = A - XH2 + XR
SUM = 0.0
C
DO 150 K = 1, NSUBS
C
150 SUM = SUM + F(START1+K*XH,NFCT) + F(START2+K*XH,NFCT)
C
SUM = SUM*XH2
C
NFUNCT = NFUNCT + 2*NSUBS
IF (KPRT.GE.1) THEN
IF (JLINE.LE.1) THEN
WRITE (KW,160) NSUBS,SUM,NFUNCT
IF (KPRT.GE.2) WRITE (KF,160) NSUBS,SUM,NFUNCT
160 FORMAT(' N =',I6,' GAUSS=',D23.16,' TOTAL NF=',I5)
ELSE
RELERR = EPS
IF (SUM.NE.0.0) RELERR = DABS(TABLE(JLINE-1)-SUM)
* / DABS(SUM)
IF (SUM.EQ.0.0 .AND. TABLE(JLINE-1).NE.0.0) RELERR =
* DABS(TABLE(JLINE-1)-SUM) / DABS(TABLE(JLINE-1))
IF (RELERR.LE.0.0) RELERR = EPS
NUMSD = -DLOG10(RELERR)
IF (NUMSD.LT.0) NUMSD = 0
WRITE (KW,170) NSUBS,SUM,NFUNCT,NUMSD
IF (KPRT.GE.2) WRITE (KF,170) NSUBS,SUM,NFUNCT,NUMSD
170 FORMAT(' N =',I6,' GAUSS=',D23.16,' TOTAL NF=',I5,
* ' EST S.D.=',I3)
ENDIF
ENDIF
C
NSUBS = 2*NSUBS
TABLE(JLINE) = SUM
180 CONTINUE
C
RETURN
END
SUBROUTINE AITKEN(TABLE,KL,KPRT,KF,KW)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
C DAVID M. SMITH 4-14-86
C
C AITKEN EXTRAPOLATION. THE VALUES TABLE(1) TO TABLE(KL) ARE USED FOR
C THE EXTRAPOLATION AND THE RESULTS ARE RETURNED IN TABLE(1) TO
C TABLE(KL-2). KL MUST BE AT LEAST 3.
C
C IF KPRT IS 1 THEN THE KL-2 VALUES ARE WRITTEN ON UNIT KW.
C IF KPRT IS 2 THE TABLE IS ALSO WRITTEN ON UNIT KF.
C
C IN THE TABLE WHICH IS WRITTEN:
C
C LINE IS THE LINE NUMBER,
C AITKEN IS THE AITKEN EXTRAPOLATION APPROXIMATION TO THE INTEGRAL,
C USING 3 VALUES FROM THE PREVIOUS COLUMN. FOR EXAMPLE,
C LINE 1 OF AN AITKEN COLUMN USES LINES 1-3 OF THE PREVIOUS
C COLUMN, LINE 4 USES LINES 4-6, ETC.
C EST S.D. IS A CONSERVATIVE ESTIMATE OF THE NUMBER OF SIGNIFICANT
C DIGITS WHICH ARE CORRECT IN THAT LINE
C
DIMENSION TABLE(20)
C
C SET EPS TO THE SIZE OF THE ROUNDING ERRORS FOR A GIVEN
C MACHINE. EPS = 1.0E-7 FOR 32 BIT MACHINES (SINGLE
C PRECISION) OR 1.0E-16 (DOUBLE PRECISION).
C
EPS = 1.0E-16
C
IF (KL.LT.3) THEN
WRITE (KW,110) KL
110 FORMAT(//' ERROR IN AITKEN. KL=',I5,' IS LESS THAN 3.'/)
RETURN
ENDIF
C
IF (KPRT.GE.1) THEN
KLM2 = KL - 2
WRITE (KW,120) KLM2
IF (KPRT.GE.2) THEN
IF (KLM2.GT.1) THEN
WRITE (KF,120) KLM2
120 FORMAT(/' AITKEN COLUMN.',I4,' ENTRIES.'/)
ELSE
WRITE (KF,130) KLM2
130 FORMAT(/' AITKEN COLUMN.',I4,' ENTRY.'/)
ENDIF
ENDIF
ENDIF
C
KLM1 = KL - 1
DO 160 JLINE = 2, KLM1
TOP = (TABLE(JLINE+1) - TABLE(JLINE))**2
BOT = TABLE(JLINE+1) - 2.0*TABLE(JLINE) + TABLE(JLINE-1)
C
IF (BOT.EQ.0.0) THEN
TABLE(JLINE-1) = TABLE(JLINE+1)
ELSE
TABLE(JLINE-1) = TABLE(JLINE+1) - TOP/BOT
ENDIF
C
IF (KPRT.GE.1) THEN
JLM1 = JLINE - 1
IF (JLINE.LE.2) THEN
WRITE (KW,140) JLM1,TABLE(JLM1)
IF (KPRT.GE.2) WRITE (KF,140) JLM1,TABLE(JLM1)
140 FORMAT(' LINE',I3,' AITKEN=',D23.16)
ELSE
RELERR = EPS
IF (TABLE(JLM1).NE.0.0) RELERR = DABS(TABLE(JLM1-1) -
* TABLE(JLM1))/DABS(TABLE(JLM1))
IF (TABLE(JLM1).EQ.0.0 .AND. TABLE(JLM1-1).NE.0.0)
* RELERR = DABS(TABLE(JLM1-1)-TABLE(JLM1)) /
* DABS(TABLE(JLM1-1))
IF (RELERR.LE.0.0) RELERR = EPS
NUMSD = -DLOG10(RELERR)
IF (NUMSD.LT.0) NUMSD = 0
WRITE (KW,150) JLM1,TABLE(JLM1),NUMSD
IF (KPRT.GE.2) WRITE (KF,150) JLM1,TABLE(JLM1),NUMSD
150 FORMAT(' LINE',I3,' AITKEN=',D23.16,
* ' EST S.D.=',I3)
ENDIF
ENDIF
C
160 CONTINUE
C
RETURN
END
FUNCTION F(X,NFCT)
C
C COMPUTE F(X) FOR FUNCTION NUMBER NFCT.
C THIS CALLING SEQUENCE ALLOWS MANY DIFFERENT FUNCTIONS TO BE USED
C EASILY DURING ONE RUN.
C
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
C
C IF NFCT IS OUTSIDE THE RANGE OF CURRENTLY DEFINED
C FUNCTIONS THEN RETURN THE FUNCTION VALUE -9.9E+20.
C ANY OUTPUT TABLES CONSISTING ENTIRELY OF THIS VALUE ARE
C ALMOST CERTAINLY CAUSED BY SENDING THE WRONG VALUE OF
C NFCT.
C
F = -9.9E+20
IF (NFCT.LT.1 .OR. NFCT.GT.6) RETURN
C
GO TO (1,2,3,4,5,6),NFCT
C
1 F = DSQRT(DEXP(X)-1.0D0)/DSIN(X)
RETURN
C
2 F = DABS(X-0.3)**0.33333
RETURN
C
C THIS FUNCTION IS 1/(X**4 + X**2 + 1)
C THE FORM USED BELOW EXECUTES FASTER.
C
3 F = 1.0/((X*X+1)*X*X + 1)
RETURN
C
4 T = X*X + 1.0
F = T/(T*X*X + 1)
RETURN
C
5 F = DSQRT(X)/(X - 1.0) - 1.0/DLOG(X)
RETURN
C
6 F = 2.0*X*X/((X-1.0)*(X+1.0)) - X/DLOG(X)
RETURN
C
END